﻿namespace MetaDrive.VisualStudio.Linq
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    public sealed class ProjectItemIterator : IEnumerable<EnvDTE.ProjectItem>
    {
        private readonly IEnumerable<EnvDTE.Project> _projects;

        public ProjectItemIterator(EnvDTE.Solution solution)
        {
            if (solution == null)
                throw new ArgumentNullException("solution");

            _projects = solution.Projects.Cast<EnvDTE.Project>();
        }

        public ProjectItemIterator(EnvDTE.Project project)
        {
            if (project == null)
                throw new ArgumentNullException("project");

            this._projects = new List<EnvDTE.Project> { project }.AsEnumerable();
        }

        public ProjectItemIterator(IEnumerable<EnvDTE.Project> projects)
        {
            if (projects == null)
                throw new ArgumentNullException("projects");

            this._projects = projects;
        }

        public IEnumerator<EnvDTE.ProjectItem> GetEnumerator()
        {
            foreach (EnvDTE.Project currentProject in _projects)
                foreach (var currentProjectItem in Enumerate(currentProject.ProjectItems))
                    yield return currentProjectItem;
        }

        IEnumerable<EnvDTE.ProjectItem> Enumerate(EnvDTE.ProjectItems projectItems)
        {
            if (projectItems != null)
            {
                foreach (EnvDTE.ProjectItem item in projectItems)
                {
                    yield return item;

                    if (item.SubProject != null)
                    {
                        foreach (EnvDTE.ProjectItem childItem in Enumerate(item.SubProject.ProjectItems))
                            yield return childItem;
                    }
                    else
                    {
                        foreach (EnvDTE.ProjectItem childItem in Enumerate(item.ProjectItems))
                            yield return childItem;
                    }
                }
            }
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}